package com.pond.pond.service.impl;

import com.pond.common.core.utils.DateUtils;
import com.pond.common.core.utils.StringUtils;
import com.pond.common.security.utils.SecurityUtils;
import com.pond.pond.domain.*;
import com.pond.pond.domain.vo.FishingTechniqueVo;
import com.pond.pond.mapper.*;
import com.pond.pond.service.IFishingTechniqueService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 钓技文章Service业务层处理
 * 
 * @author pond
 * @date 2024-01-15
 */
@Service
public class FishingTechniqueServiceImpl implements IFishingTechniqueService 
{
    @Autowired
    private FishingTechniqueMapper fishingTechniqueMapper;

    @Autowired
    private FishingTechniqueLikeMapper fishingTechniqueLikeMapper;

    @Autowired
    private FishingTechniqueFavoriteMapper fishingTechniqueFavoriteMapper;

    @Autowired
    private FishingTechniqueCommentMapper fishingTechniqueCommentMapper;

    @Autowired
    private FishingTechniqueCommentLikeMapper fishingTechniqueCommentLikeMapper;

    /**
     * 查询钓技文章
     * 
     * @param id 钓技文章主键
     * @return 钓技文章
     */
    @Override
    public FishingTechnique selectFishingTechniqueById(Long id)
    {
        return fishingTechniqueMapper.selectFishingTechniqueById(id);
    }

    /**
     * 查询钓技文章详情（包含用户交互状态）
     * 
     * @param id 钓技文章主键
     * @param userId 用户ID
     * @return 钓技文章
     */
    @Override
    public FishingTechniqueVo selectFishingTechniqueDetailById(Long id, Long userId)
    {
        FishingTechniqueVo vo = fishingTechniqueMapper.selectFishingTechniqueDetailById(id, userId);
        // 标签处理在Mapper的XML中完成，这里不需要额外处理
        return vo;
    }

    /**
     * 查询钓技文章列表
     * 
     * @param fishingTechnique 钓技文章
     * @return 钓技文章
     */
    @Override
    public List<FishingTechnique> selectFishingTechniqueList(FishingTechnique fishingTechnique)
    {
        return fishingTechniqueMapper.selectFishingTechniqueList(fishingTechnique);
    }

    /**
     * 查询钓技文章列表（包含用户交互状态）
     * 
     * @param fishingTechnique 钓技文章
     * @param userId 用户ID
     * @return 钓技文章集合
     */
    @Override
    public List<FishingTechniqueVo> selectFishingTechniqueListWithUser(FishingTechnique fishingTechnique, Long userId)
    {
        List<FishingTechniqueVo> list = fishingTechniqueMapper.selectFishingTechniqueListWithUser(fishingTechnique, userId);
        // 标签处理在Mapper的XML中完成，这里不需要额外处理
        return list;
    }

    /**
     * 新增钓技文章
     * 
     * @param fishingTechnique 钓技文章
     * @return 结果
     */
    @Override
    public int insertFishingTechnique(FishingTechnique fishingTechnique)
    {
        fishingTechnique.setCreateTime(DateUtils.getNowDate());
        fishingTechnique.setCreateBy(SecurityUtils.getUsername());
        return fishingTechniqueMapper.insertFishingTechnique(fishingTechnique);
    }

    /**
     * 修改钓技文章
     * 
     * @param fishingTechnique 钓技文章
     * @return 结果
     */
    @Override
    public int updateFishingTechnique(FishingTechnique fishingTechnique)
    {
        fishingTechnique.setUpdateTime(DateUtils.getNowDate());
        fishingTechnique.setUpdateBy(SecurityUtils.getUsername());
        return fishingTechniqueMapper.updateFishingTechnique(fishingTechnique);
    }

    /**
     * 批量删除钓技文章
     * 
     * @param ids 需要删除的钓技文章主键
     * @return 结果
     */
    @Override
    public int deleteFishingTechniqueByIds(Long[] ids)
    {
        return fishingTechniqueMapper.deleteFishingTechniqueByIds(ids);
    }

    /**
     * 删除钓技文章信息
     * 
     * @param id 钓技文章主键
     * @return 结果
     */
    @Override
    public int deleteFishingTechniqueById(Long id)
    {
        return fishingTechniqueMapper.deleteFishingTechniqueById(id);
    }

    /**
     * 增加文章阅读量
     * 
     * @param id 文章ID
     * @return 新的阅读量
     */
    @Override
    public int incrementReadCount(Long id)
    {
        fishingTechniqueMapper.incrementReadCount(id);
        FishingTechnique technique = fishingTechniqueMapper.selectFishingTechniqueById(id);
        return technique != null ? technique.getReadCount() : 0;
    }

    /**
     * 点赞/取消点赞文章
     * 
     * @param id 文章ID
     * @param userId 用户ID
     * @return 操作结果
     */
    @Override
    @Transactional
    public Map<String, Object> toggleLike(Long id, Long userId)
    {
        Map<String, Object> result = new HashMap<>();
        
        FishingTechniqueLike existingLike = fishingTechniqueLikeMapper.selectByTechniqueAndUser(id, userId);
        boolean isLiked;
        
        if (existingLike != null) {
            // 取消点赞
            fishingTechniqueLikeMapper.deleteByTechniqueAndUser(id, userId);
            fishingTechniqueMapper.decrementLikeCount(id);
            isLiked = false;
        } else {
            // 点赞
            FishingTechniqueLike like = new FishingTechniqueLike();
            like.setTechniqueId(id);
            like.setUserId(userId);
            like.setCreateTime(new Date());
            fishingTechniqueLikeMapper.insertFishingTechniqueLike(like);
            fishingTechniqueMapper.incrementLikeCount(id);
            isLiked = true;
        }
        
        FishingTechnique technique = fishingTechniqueMapper.selectFishingTechniqueById(id);
        result.put("isLiked", isLiked);
        result.put("likeCount", technique.getLikeCount());
        
        return result;
    }

    /**
     * 收藏/取消收藏文章
     * 
     * @param id 文章ID
     * @param userId 用户ID
     * @return 操作结果
     */
    @Override
    @Transactional
    public Map<String, Object> toggleFavorite(Long id, Long userId)
    {
        Map<String, Object> result = new HashMap<>();
        
        FishingTechniqueFavorite existingFavorite = fishingTechniqueFavoriteMapper.selectByTechniqueAndUser(id, userId);
        boolean isFavorited;
        
        if (existingFavorite != null) {
            // 取消收藏
            fishingTechniqueFavoriteMapper.deleteByTechniqueAndUser(id, userId);
            fishingTechniqueMapper.decrementFavoriteCount(id);
            isFavorited = false;
        } else {
            // 收藏
            FishingTechniqueFavorite favorite = new FishingTechniqueFavorite();
            favorite.setTechniqueId(id);
            favorite.setUserId(userId);
            favorite.setCreateTime(new Date());
            fishingTechniqueFavoriteMapper.insertFishingTechniqueFavorite(favorite);
            fishingTechniqueMapper.incrementFavoriteCount(id);
            isFavorited = true;
        }
        
        FishingTechnique technique = fishingTechniqueMapper.selectFishingTechniqueById(id);
        result.put("isFavorited", isFavorited);
        result.put("favoriteCount", technique.getFavoriteCount());
        
        return result;
    }

    /**
     * 查询用户收藏的文章列表
     * 
     * @param userId 用户ID
     * @return 文章列表
     */
    @Override
    public List<FishingTechniqueVo> selectUserFavorites(Long userId)
    {
        return fishingTechniqueMapper.selectUserFavorites(userId);
    }

    /**
     * 查询热门文章
     * 
     * @param limit 数量限制
     * @param type 排序类型：read-阅读量，like-点赞数，favorite-收藏数
     * @return 文章列表
     */
    @Override
    public List<FishingTechniqueVo> selectHotTechniques(Integer limit, String type)
    {
        if (limit == null || limit <= 0) {
            limit = 10;
        }
        if (StringUtils.isEmpty(type)) {
            type = "read";
        }
        return fishingTechniqueMapper.selectHotTechniques(limit, type);
    }

    /**
     * 查询所有分类及其文章数量
     * 
     * @return 分类统计
     */
    @Override
    public List<Map<String, Object>> selectCategoryStats()
    {
        return fishingTechniqueMapper.selectCategoryStats();
    }

    /**
     * 查询热门标签
     * 
     * @param limit 数量限制
     * @return 标签统计
     */
    @Override
    public List<Map<String, Object>> selectHotTags(Integer limit)
    {
        if (limit == null || limit <= 0) {
            limit = 20;
        }
        return fishingTechniqueMapper.selectHotTags(limit);
    }

    /**
     * 获取文章统计信息
     * 
     * @param id 文章ID
     * @return 统计信息
     */
    @Override
    public Map<String, Object> getArticleStats(Long id)
    {
        FishingTechnique technique = fishingTechniqueMapper.selectFishingTechniqueById(id);
        Map<String, Object> stats = new HashMap<>();
        if (technique != null) {
            stats.put("readCount", technique.getReadCount());
            stats.put("likeCount", technique.getLikeCount());
            stats.put("favoriteCount", technique.getFavoriteCount());
            stats.put("commentCount", technique.getCommentCount());
        }
        return stats;
    }

    /**
     * 发表评论
     * 
     * @param comment 评论信息
     * @return 评论ID
     */
    @Override
    @Transactional
    public Long addComment(FishingTechniqueComment comment)
    {
        comment.setCreateTime(new Date());
        comment.setStatus("1");
        fishingTechniqueCommentMapper.insertFishingTechniqueComment(comment);
        
        // 增加文章评论数
        fishingTechniqueMapper.incrementCommentCount(comment.getTechniqueId());
        
        return comment.getId();
    }

    /**
     * 删除评论
     * 
     * @param commentId 评论ID
     * @param userId 用户ID
     * @return 结果
     */
    @Override
    @Transactional
    public boolean deleteComment(Long commentId, Long userId)
    {
        FishingTechniqueComment comment = fishingTechniqueCommentMapper.selectFishingTechniqueCommentById(commentId);
        if (comment == null) {
            return false;
        }
        
        // 检查权限：只能删除自己的评论
        if (!comment.getUserId().equals(userId)) {
            return false;
        }
        
        int result = fishingTechniqueCommentMapper.deleteFishingTechniqueCommentById(commentId);
        if (result > 0) {
            // 减少文章评论数
            fishingTechniqueMapper.decrementCommentCount(comment.getTechniqueId());
            return true;
        }
        
        return false;
    }

    /**
     * 点赞/取消点赞评论
     * 
     * @param commentId 评论ID
     * @param userId 用户ID
     * @return 操作结果
     */
    @Override
    @Transactional
    public Map<String, Object> toggleCommentLike(Long commentId, Long userId)
    {
        Map<String, Object> result = new HashMap<>();
        
        FishingTechniqueCommentLike existingLike = fishingTechniqueCommentLikeMapper.selectByCommentAndUser(commentId, userId);
        boolean isLiked;
        
        if (existingLike != null) {
            // 取消点赞
            fishingTechniqueCommentLikeMapper.deleteByCommentAndUser(commentId, userId);
            fishingTechniqueCommentMapper.decrementLikeCount(commentId);
            isLiked = false;
        } else {
            // 点赞
            FishingTechniqueCommentLike like = new FishingTechniqueCommentLike();
            like.setCommentId(commentId);
            like.setUserId(userId);
            like.setCreateTime(new Date());
            fishingTechniqueCommentLikeMapper.insertFishingTechniqueCommentLike(like);
            fishingTechniqueCommentMapper.incrementLikeCount(commentId);
            isLiked = true;
        }
        
        FishingTechniqueComment comment = fishingTechniqueCommentMapper.selectFishingTechniqueCommentById(commentId);
        result.put("isLiked", isLiked);
        result.put("likeCount", comment.getLikeCount());
        
        return result;
    }

    /**
     * 查询文章评论列表
     * 
     * @param techniqueId 文章ID
     * @param userId 当前用户ID
     * @return 评论列表
     */
    @Override
    public List<FishingTechniqueComment> selectCommentsByTechniqueId(Long techniqueId, Long userId)
    {
        List<FishingTechniqueComment> comments = fishingTechniqueCommentMapper.selectCommentsByTechniqueId(techniqueId, userId);
        
        // 递归查询每个评论的回复
        for (FishingTechniqueComment comment : comments) {
            loadRepliesRecursively(comment, userId);
        }
        
        return comments;
    }
    
    /**
     * 递归加载评论的回复
     * 
     * @param comment 父评论
     * @param userId 当前用户ID
     */
    private void loadRepliesRecursively(FishingTechniqueComment comment, Long userId) {
        List<FishingTechniqueComment> replies = fishingTechniqueCommentMapper.selectRepliesByParentId(comment.getId(), userId);
        
        // 为每个回复递归加载其子回复
        for (FishingTechniqueComment reply : replies) {
            loadRepliesRecursively(reply, userId);
        }
        
        comment.setReplies(replies);
    }

    @Override
    public List<Map<String, Object>> selectUserCommentsWithTechniqueTitle(Long userId) {
        return fishingTechniqueMapper.selectUserCommentsWithTechniqueTitle(userId);
    }
}